package testrj.traverser.jsonmaker;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import testrj.traverser.NodeStrategy;
import testrj.traverser.StrategyFactory;
import testrj.traverser.genericstrategies.AbstractStrategy;

public class JsonMakerStrategies implements StrategyFactory {
	private AbstractStrategy anyObjectNodeStrategy = null;
	private List<NodeStrategy> default_strategies = null;
	private Map<String, NodeStrategy> custom_strategies = null;

	public Collection<NodeStrategy> customStrategiesAsList() {
		return custom_strategies.values();
	}

	public List<NodeStrategy> defaultStrategies() {
		return default_strategies;
	}

	public Map<String, NodeStrategy> customStrategies() {
		return custom_strategies;
	}

	public NodeStrategy anyObjectNodeStrategy() {
		return anyObjectNodeStrategy;
	}

	public void unRegisterNodeStrategy(Class<?> clazz) {
		String key = clazz.getName();
		if (custom_strategies.containsKey(key)) {
			custom_strategies.remove(key);
		}
	}

	public void registerNodeStrategy(NodeStrategy NodeStrategy, boolean replaceIfExists) {
		String key = NodeStrategy.getClass().getName();
		if (custom_strategies.containsKey(key)) {
			if (replaceIfExists) {
				custom_strategies.remove(key);
				custom_strategies.put(key, NodeStrategy);
			}
		} else {
			custom_strategies.put(key, NodeStrategy);
		}
	}

	public void initialize() {
		setUpdefaultStrategies();
		custom_strategies = new HashMap<String, NodeStrategy>();
		anyObjectNodeStrategy = new FieldBasedNodeStrategy();
	}

	private void setUpdefaultStrategies() {
		if (default_strategies != null)
			return;
		default_strategies = new ArrayList<NodeStrategy>();
		AbstractStrategy toJsonNodeStrategy = new LeafNodeStrategy();
		AbstractStrategy iterableNodeStrategy = new IterableNodeStrategy();
		AbstractStrategy mapNodeStrategy = new MapNodeStrategy();
		AbstractStrategy arrayNodeStrategy = new ArrayNodeStrategy();

		default_strategies.add(toJsonNodeStrategy);
		default_strategies.add(iterableNodeStrategy);
		default_strategies.add(mapNodeStrategy);
		default_strategies.add(arrayNodeStrategy);
	}

	public static StrategyFactory newInstance() {
		StrategyFactory strategies = new JsonMakerStrategies();
		strategies.initialize();
		return strategies;
	}

	public void handleException(Throwable th) {

	}

	private JsonMakerStrategies() {
	}
}